package com.mybatis_demo.frame.session.defaults;

import com.mybatis_demo.frame.reflection.ReflectorUtil;
import com.mybatis_demo.frame.session.SqlSession;
import com.mybatis_demo.frame.session.config.Configuration;
import com.mybatis_demo.frame.session.mapping.SqlMap;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DefaultSqlSession implements SqlSession {
    private Configuration configuration;

    public Configuration getConfiguration() {
        return configuration;
    }

    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public <T> List<T> findAll(String statement) {
        try {
            //1. 获取连接，使用连接池方案
            Connection connection = configuration.getDataSource().getConnection();
            //2. 获取prepareStatemen（包含sql）
            SqlMap sqlMap = configuration.getSqlMaps().get(statement);

            PreparedStatement preparedStatement = connection.prepareStatement(sqlMap.getSql());
            ResultSet resultSet = preparedStatement.executeQuery();

            //拿到了想要封装的返回值类型
            Class clazz = sqlMap.getClazz();
            //处理结果  封装
            return handlerResultSet(clazz, resultSet);

        } catch (Exception throwables) {
            throw new RuntimeException(throwables);
        }
    }

    private List handlerResultSet(Class clazz, ResultSet resultSet) throws SQLException, IllegalAccessException, InstantiationException {
        List list = new ArrayList();
        //想要一个clazz类型的集合
        //遍历resultSet 将结果封装到List
        //获取元信息
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();
        //想办法获取所有列（字段）的名字
        List<String> columnNames = new ArrayList<>();
        for (int i = 1; i <= columnCount; i++) {
            columnNames.add(metaData.getColumnName(i));
        }
        //columnNames集合中存在所有列名了
        //取列中的值
        while(resultSet.next()){
            Object o = clazz.newInstance();
            for (String columnName : columnNames) {
                Object columnValue = resultSet.getObject(columnName);
                ReflectorUtil.set(o,columnName,columnValue);
            }
            list.add(o);
        }
        return list;
    }
}
